package com.insta.formation.library.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.insta.formation.library.Libraryfactory;
import com.insta.formation.library.Properties;
import com.insta.formation.library.dao.IRentDao;
import com.insta.formation.library.dao.JdbcTools;
import com.insta.formation.library.model.IBook;
import com.insta.formation.library.model.IRentBook;
import com.insta.formation.library.model.IUser;

public class RentDaoImpl implements IRentDao
{
	final private static Logger LOGGER = LoggerFactory.getLogger(RentDaoImpl.class);

	public IRentBook create(IRentBook rent)
	{
		try {
			String query = "INSERT INTO " + Properties.RENT_TABLE + " (id_user, id_book, start_date, return_date , is_return) VALUES (?,?,?,?,?)";

			Connection conn = JdbcTools.INSTANCE.getConnection();
			PreparedStatement stmt = conn.prepareStatement(query, java.sql.Statement.RETURN_GENERATED_KEYS);

			stmt.setInt(1, rent.getUser().getId());
			stmt.setInt(2, rent.getBook().getId());
			stmt.setTimestamp(3, new Timestamp(rent.getStartDate().getTime()));
			if (rent.getReturnDate() != null) {
				stmt.setTimestamp(4, new Timestamp(rent.getReturnDate().getTime()));
			}
			else {
				stmt.setTimestamp(4, null);
			}
			stmt.setBoolean(5, rent.isReturn());

			stmt.execute();
			ResultSet rs = stmt.getGeneratedKeys();
			if (rs.next()) {
				rent = Libraryfactory.INSTANCE.createRentBook(rs.getBigDecimal(1).intValue(), rent.getUser(), rent.getBook(), rent.getStartDate(),
						rent.getReturnDate(), rent.isReturn());
			}
			stmt.close();
		} catch (SQLException e) {
			LOGGER.error(e.getMessage());
			// e.printStackTrace();
			rent = null;
		}

		return rent;
	}

	public IRentBook find(int id)
	{
		IRentBook rent = null;

		try {
			String query = "SELECT * FROM " + Properties.RENT_TABLE + " WHERE id=?";
			Connection conn = JdbcTools.INSTANCE.getConnection();
			PreparedStatement stmt = conn.prepareStatement(query);
			stmt.setInt(1, id);
			ResultSet rs = stmt.executeQuery();
			if (rs.next()) {
				rent = Libraryfactory.INSTANCE.createRentBook(rs.getInt("ID"), Libraryfactory.INSTANCE.createUserDao().find(rs.getInt("ID_USER")),
						Libraryfactory.INSTANCE.createBookDao().find(rs.getInt("ID_BOOK")), rs.getTimestamp("START_DATE"), rs.getTimestamp("RETURN_DATE"),
						rs.getBoolean("IS_RETURN"));
			}
			stmt.close();

		} catch (SQLException e) {
			LOGGER.error(e.getMessage());
			// e.printStackTrace();
			rent = null;
		}
		return rent;
	}

	public IRentBook update(IRentBook rent)
	{
		try {
			String query = "UPDATE " + Properties.RENT_TABLE + " SET return_date=?, is_return=? WHERE id=?";

			Connection conn = JdbcTools.INSTANCE.getConnection();
			PreparedStatement stmt = conn.prepareStatement(query, java.sql.Statement.RETURN_GENERATED_KEYS);

			stmt.setTimestamp(1, new Timestamp(rent.getReturnDate().getTime()));
			stmt.setBoolean(2, rent.isReturn());
			stmt.setInt(3, rent.getId());

			stmt.execute();
			ResultSet rs = stmt.getGeneratedKeys();
			if (rs.next()) {
				rent = Libraryfactory.INSTANCE.createRentBook(rs.getBigDecimal(1).intValue(), rent.getUser(), rent.getBook(), rent.getStartDate(),
						rent.getReturnDate(), rent.isReturn());
			}
			stmt.close();
		} catch (SQLException e) {
			LOGGER.error(e.getMessage());
			// e.printStackTrace();
			rent = null;
		}

		return rent;
	}

	public List<IRentBook> find(IUser user)
	{
		List<IRentBook> rents = new ArrayList<IRentBook>();

		try {
			String query = "SELECT * FROM " + Properties.RENT_TABLE + " WHERE id_user=?";
			Connection conn = JdbcTools.INSTANCE.getConnection();
			PreparedStatement stmt = conn.prepareStatement(query);
			stmt.setInt(1, user.getId());
			ResultSet rs = stmt.executeQuery();
			while (rs.next()) {
				IBook book = Libraryfactory.INSTANCE.createBookDao().find(rs.getInt("id_book"));
				IRentBook rent = Libraryfactory.INSTANCE.createRentBook(rs.getInt("id"), user, book, rs.getTimestamp("start_date"),
						rs.getTimestamp("return_date"), rs.getBoolean("is_return"));
				rents.add(rent);
			}
			stmt.close();

		} catch (SQLException e) {
			LOGGER.error(e.getMessage());
			// e.printStackTrace();
			rents = null;
		}
		return rents;
	}

	public List<IRentBook> find(IBook book)
	{
		List<IRentBook> rents = new ArrayList<IRentBook>();

		try {
			String query = "SELECT * FROM " + Properties.RENT_TABLE + " WHERE id_book=?";
			Connection conn = JdbcTools.INSTANCE.getConnection();
			PreparedStatement stmt = conn.prepareStatement(query);
			stmt.setInt(1, book.getId());
			ResultSet rs = stmt.executeQuery();
			while (rs.next()) {
				IUser user = Libraryfactory.INSTANCE.createUserDao().find(rs.getInt("id_user"));
				IRentBook rent = Libraryfactory.INSTANCE.createRentBook(rs.getInt("id"), user, book, rs.getTimestamp("start_date"),
						rs.getTimestamp("return_date"), rs.getBoolean("is_return"));
				rents.add(rent);
			}
			stmt.close();

		} catch (SQLException e) {
			LOGGER.error(e.getMessage());
			// e.printStackTrace();
			rents = null;
		}
		return rents;
	}

	public void delete(IRentBook rent)
	{
		try {
			String query = "DELETE FROM " + Properties.RENT_TABLE + " WHERE id=?";
			Connection conn = JdbcTools.INSTANCE.getConnection();
			PreparedStatement stmt = conn.prepareStatement(query);
			stmt.setInt(1, rent.getId());
			stmt.execute();
			stmt.close();

		} catch (SQLException e) {
			LOGGER.error(e.getMessage());
			// e.printStackTrace();
		}

	}
}
